<template>
  <common-card class="grade_distribution">
    <template #title>等级分布</template>
    <div class="content">
      <div
        class="chart"
        ref="chartRef"
        style="width: 100%; height: 396px"
      ></div>
      <div class="detail">
        <ul class="list">
          <li
            v-for="(item, index) in getList"
            :key="index"
            class="list__item"
            :class="{ active: active.type === index }"
            @mouseenter="active.type = index"
          >
            <p class="left">
              <span class="num" :style="{ color: getColor(item.key) }"
                >{{ item.desc }}: {{ item.num || 0 }}人</span
              >
              <span class="tips">{{ item.desc }}{{ item.range }}</span>
            </p>
          </li>
        </ul>
        <div
          class="detail__right"
          :class="{ 'no-has-data': getActiveList.length === 0 }"
        >
          <template v-if="getActiveList.length > 0">
            <button
              class="btn"
              v-for="(item, index) in getActiveList"
              :key="index"
            >
              <template v-if="props.activeTab === 'grade'"
                ><span>{{ item.class_name || '' }}</span>
                <span>{{ item.count || 0 }}人</span></template
              >
              <template v-else>
                <span>{{ item.student_name || '' }}</span>
                <span>{{ getPercent(item.rate || 0) || 0 }}%</span>
              </template>
            </button>
          </template>
          <no-data class="no-data" v-else>暂无数据</no-data>
        </div>
      </div>
    </div>
  </common-card>
</template>
<script setup>
import CommonCard from '../components/CommonCard.vue'
import useCharts from '@/utils/echart/index'
import { getGradeLevel, getClassLevel } from '@/apis/situation-report/index'
import { ref, watchEffect, computed, reactive } from 'vue'
import { useSituationReport } from '@/stores/situation-report'
import { getPercent } from '../utils'
const situationReport = useSituationReport()
const chartRef = ref(null)
const { setOption, getInstance } = useCharts(chartRef, true, true, 'light')
const active = reactive({
  type: 0
})
const props = defineProps({
  activeTab: {
    default: 'grade',
    type: String
  }
})

const getActiveList = computed(() => {
  return getList.value[active.type]?.children || []
})

const GRADE = {
  EXCELLENT: 'excellent',
  GOOD: 'good',
  PASS: 'pass',
  NO_PASS: 'no_pass'
}

const total = ref(0)

const dataList = ref([
  {
    desc: '优秀',
    range: '[90%~100%]',
    num: 0,
    key: GRADE.EXCELLENT,
    children: []
  },
  {
    desc: '良好',
    range: '[80%~90%）',
    key: GRADE.GOOD,
    num: 0,
    children: []
  },

  {
    desc: '合格',
    range: '[60%~80%）',
    num: 0,
    key: GRADE.PASS,
    children: []
  },
  {
    desc: '待合格',
    range: '[0%~60%）',
    key: GRADE.NO_PASS,
    num: 0,
    children: []
  }
])

const studentList = ref([
  {
    desc: '优秀',
    range: '[90%~100%]',
    num: 0,
    key: GRADE.EXCELLENT,
    children: []
  },
  {
    desc: '良好',
    range: '[80%~90%）',
    key: GRADE.GOOD,
    num: 0,
    children: []
  },

  {
    desc: '合格',
    range: '[60%~80%）',
    num: 0,
    key: GRADE.PASS,
    children: []
  },
  {
    desc: '待合格',
    range: '[0%~60%）',
    key: GRADE.NO_PASS,
    num: 0,
    children: []
  }
])

const getList = computed(() => {
  if (props.activeTab === 'grade') return dataList.value
  return studentList.value
})

const getColor = key => {
  let color = ''
  switch (key) {
    case GRADE.EXCELLENT:
      color = '#4CDFC0'
      break
    case GRADE.GOOD:
      color = '#8AC7FF'
      break

    case GRADE.PASS:
      color = '#FFBE21'
      break
    case GRADE.NO_PASS:
      color = '#FF7B73'
      break
  }
  return color
}

const getOption = () => {
  const option = {
    color: ['#4CDFC0', '#8AC7FF', '#FFBE21', '#FF7B73'],
    series: [
      {
        name: '等级分布',
        type: 'pie',
        radius: [55, 90],
        center: ['50%', '45%'],
        avoidLabelOverlap: false,
        label: {
          color: 'inherit',
          formatter: params => {
            return `{name|${params.data.name}}\n{ratio|占比${
              params.value || 0
            }%}`
          },
          rich: {
            name: {
              fontSize: 14,
              fontWeight: 400
            },
            ratio: {
              padding: [5, 0, 0, 0],
              fontSize: 14,
              fontWeight: 700
            }
          }
        },
        data: getFilteredList.value,
        emphasis: {
          scale: false // 设置不放大
        }
      }
    ]
  }
  return option
}

const getFilteredList = computed(() => {
  const list = dataList.value.map((item, index) => {
    return {
      value:
        props.activeTab === 'grade'
          ? getPercent(dataList.value[index].num / total.value)
          : getPercent(studentList.value[index].num / total.value),
      name: item.desc,
      labelLine: {
        length: 12,
        show:
          props.activeTab === 'grade'
            ? dataList.value[index].num > 0
            : studentList.value[index].num > 0
      },
      label: {
        show:
          props.activeTab === 'grade'
            ? dataList.value[index].num > 0
            : studentList.value[index].num > 0
      }
    }
  })
  return list
})

const getLevel = async () => {
  const {
    data: { list }
  } = await getGradeLevel(situationReport.search)
  dataList.value.forEach((item, index) => {
    total.value += list[index].count || 0
    dataList.value[index].num = list[index].count || 0
    dataList.value[index].children = list[index].class_count || []
  })
}

const getClassData = async () => {
  const {
    data: { list }
  } = await getClassLevel(situationReport.search)
  studentList.value.forEach((item, index) => {
    total.value += list[index].count || 0
    studentList.value[index].num = list[index].count || 0
    studentList.value[index].children = list[index].students || []
  })
}

watchEffect(async () => {
  if (
    situationReport.search.class_id ||
    situationReport.search.grade_id ||
    situationReport.search.subject_id
  ) {
    let index = 0
    total.value = 0
    if (props.activeTab === 'grade') {
      await getLevel()
      index = dataList.value.findIndex(item => item.num > 0)
    } else {
      await getClassData()
      index = studentList.value.findIndex(item => item.num > 0)
    }
    if (index > -1) {
      active.type = index
    } else {
      active.type = 0
    }
    setOption(getOption())
    getInstance()?.on('click', params => {
      active.type = params.dataIndex
    })
  }
})
</script>
<style lang="less" scoped>
.grade_distribution {
  .content {
    display: flex;
    gap: 28px;

    .chart {
      flex: 1;
    }

    .detail {
      width: 590px;
      height: fit-content;
      display: flex;

      .list {
        width: fit-content;
        display: flex;
        flex-direction: column;

        li {
          list-style-type: none;
        }

        &__item {
          display: flex;
          cursor: pointer;

          .left {
            padding: 24px 0 24px 32px;
            background: #f6f8fe;
            border: 1px solid #f2f3f4;
            width: 162px;
            gap: 4px;
            display: flex;
            flex-direction: column;
            margin-right: 76px;

            .num {
              font-size: 14px;
              font-weight: 500;
            }

            .tips {
              font-size: 12px;
              font-weight: 400;
              color: rgb(4 11 26 / 0.3);
            }
          }

          &.active {
            .left {
              background: #fff;
            }
          }
        }
      }

      &__right {
        max-height: 380px;
        overflow-y: auto;
        border: 1px solid #f2f3f4;
        padding: 24px;
        flex: 1;
        display: flex;
        flex-wrap: wrap;
        align-content: flex-start;
        gap: 16px;

        &::-webkit-scrollbar {
          width: 3px !important;
          height: 20px !important;
        }

        &.no-has-data {
          padding: 0;
          align-items: center;
        }

        :deep(.no-data) {
          img {
            width: 310px !important;
            height: 310px !important;
          }

          overflow: hidden;
        }

        .btn {
          width: 167px;
          height: 36px;
          padding: 0 16px;
          display: inline-flex;
          justify-content: space-between;
          align-items: center;
          border: 1px solid #e7e9eb;
          border-radius: 8px;
          background: #fff;

          span {
            font-size: 14px;
            font-weight: 500;
            color: rgb(4 11 26 / 0.5);
          }
        }
      }
    }
  }
}
</style>
